#ifndef EASYASIO_NET_TCP_CLIENT_HPP 
#define EASYASIO_NET_TCP_CLIENT_HPP 

#include <array>
#include <memory>

#include <asio.hpp>
#include <iostream>

#include "../base/utils.hpp"
#include "callbacks.hpp"
#include "buffer.hpp"
#include "tcp_connection.hpp"

namespace easyasio {
namespace net {

class TcpClient : public std::enable_shared_from_this<TcpClient>, private noncopyable 
{
public:
    enum  State { Disconnected, Connecting, Connected };
    TcpClient(asio::io_service& io_service, const std::string& remote_addr, int remote_port);
	~TcpClient() { } 

    State state() const { return state_; }

    void asynConnect();
    void stop();

    void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; } 
    void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; }
    void setWriteCompleteCallback(const WriteCompleteCallback& cb) { writeCompleteCallback_ = cb; }

private:
    void connectInLoop();
    void handleConnect(const asio::error_code& error);
    void setState(State  s) { state_ = s; }

private:
    asio::io_service& io_service_; 
    std::string remote_addr_; 
    int remote_port_;
    TcpConnectionPtr conn_;

    ConnectionCallback connectionCallback_;
    MessageCallback messageCallback_;
    WriteCompleteCallback writeCompleteCallback_;

    bool connect_;
    State state_;
    bool retry_;
};

} // easyasio
} // net 

#endif // EASYASIO_NET_TCP_CLIENT_HPP 
